package com.example.demo_okhttp_retrofit

import android.os.Bundle
import android.util.Log
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import okhttp3.Call
import okhttp3.OkHttp
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import retrofit2.Retrofit
import java.io.IOException
import java.lang.reflect.Method
import java.lang.reflect.Proxy

/**
 一. okhttp的原理
     1.创建OkhttpClient.Buider():里面初始化一些重要属性
         dispatcher调度器：三个任务队列(正在运行的同步任务队列/正在运行异步任务队列/准备执行异步任务队列)+线程池
         connectionPool：连接池，网络连接可以进行复用，最多5个，每个链接最终保持5分钟
         connectTimeOut/readTimeOut/writeTimeOut：默认十秒
     2.创建request对象：url网址/请求方式默认是get/请求头/请求体/tag
     3.client发起request得到RealCall
     4.同步和异步：
     同步：execute()方法：调用dispatcher调度器将RealCall放在正在运行的同步任务队列中
     异步：enqueue()方法：调用dispatcher调度器new AsyncCall，判断正在执行的异步任务队列是否超过最大requet数量64，若超过将AsyncCall放在准备异步任务队列，若没超过将AsyncCall放在正在异步任务队列中并交给线程池执行该任务
     5.无论是同步还是异步都会执行getResponseWithInterceptorChain()获得最终的response结果
     （1）里面7种拦截器：自定义Inteceptor—》重连和重定向拦截器—〉桥拦截器(gZip)—>缓存拦截器—>链接拦截器->自定义NetWorkInteceptor-》CallServerInteceptor真正发送数据和读取数据
     （2）将7种拦截封装在责任链中，最后执行得到response结果
二。七大拦截器作用



 一.代理模式
 1。代理模式是什么？我们无法直接访问一个对象的时候可以通过代理对象访问+被访问的对象不想暴露全部内容时，可以通过代理去掉不想被访问的内容
 2。代理模式几种？
 （1）静态代理
 （2）动态代理：JDK原生动态代理：Proxy.newProxyInstance() 缺点：只能代理接口
 （3）动态代理：Cglib:既能代理接口也能代理具体类 但是无法代理final修饰的方法
 3。用处？retrofit源码动态代理 +各种hook技术+插件化热更新
 二.Retrofit原理解析
 1.retrofit：是基于Okhttp的restful风格网络框架
 2.api接口添加注解GET或POST请求
 （1）GET请求 @Query设置参数
 （2）POST请求 普通表单提交 @Field注解
 （3）POST请求 提交的json数据 @Body注解
 （4）POST请求 上传文件 @Body MultipartBody.Part类型 而且方法上添加 @Multipart
 3.查看retrofit的create方法的源码中采用动态代理和反射技术解析api接口中方法的注解注解和信息参数构建一个Http请求对象
 4.retrofit会将请求对象发给Okhttp库执行请求，返回Call对象







 */
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(R.layout.activity_main)

//        testOkhttp()
        testProxy()

        val retrofit = Retrofit.Builder().build()
        retrofit.create(Api::class.java)
    }
    //动态代理
    private fun testProxy() {
        val myapi = MyApi()
        val api:Api = Proxy.newProxyInstance(
            Api::class.java.classLoader,
            arrayOf(Api::class.java),
            object : java.lang.reflect.InvocationHandler {
                override fun invoke(proxy: Any?, method: Method?, args: Array<out Any>?): Any {
                    val name = method?.name //方法名称
                    val annotations = method?.annotations //方法上的注解
                    Log.d("代理接口中的方法", "invoke:参数$args ")
                    Log.d("代理接口中的方法", "invoke:方法名称$name ")

                    //构建okhttpRequest对象
                    return method?.invoke(myapi, args)!!
                }
            }) as Api

        api.getData("hahah")
    }

    private fun testOkhttp() {
        //1.client
        val client = OkHttpClient.Builder()
//            .addInterceptor()
//            .addNetworkInterceptor()
            .build()
        //2: request
        val request = Request.Builder()
            .get()
            .addHeader("token","")
            .url("")
            .build();
        //3:client发起request请求，返回call
        val call = client.newCall(request)
        //4:异步请求
        call.enqueue(object : okhttp3.Callback{
            override fun onFailure(call: Call, e: IOException) {

            }

            override fun onResponse(call: Call, response: Response) {
                //response获得结果
            }

        })
        //5:同步
        val response = call.execute()//获得结果，阻塞当前线程


    }
}